// Simple Blackjack implementation const SUITS = ['♠','♥','♦','♣']; const RANKS = ['A','2','3','4','5','6','7','8','9','10','J','Q','K']; // DOM const dealerHandEl = document.getElementById('dealer-hand'); const playerHandEl = document.getElementById('player-hand'); const dealerValueEl = document.getElementById('dealer-value'); const playerValueEl = document.getElementById('player-value'); const balanceEl = document.getElementById('balance'); const betInput = document.getElementById('bet-input'); const betBtn = document.getElementById('bet-btn'); const currentBetEl = document.getElementById('current-bet'); const hitBtn = document.getElementById('hit'); const standBtn = document.getElementById('stand'); const doubleBtn = document.getElementById('double'); const newRoundBtn = document.getElementById('new-round'); const messageEl = document.getElementById('message'); let deck = []; let dealer = []; let player = []; let dealerHidden = true; let balance = 1000; let currentBet = 0; let inRound = false; function makeDeck(){ deck = []; for(const s of SUITS){ for(const r of RANKS){ deck.push({suit:s,rank:r}); } } } function shuffle(){ for(let i=deck.length-1;i>0;i--){ const j = Math.floor(Math.random()*(i+1)); [deck[i],deck[j]] = [deck[j],deck[i]]; } } function cardValue(card){ const r = card.rank; if(r==='A') return [1,11]; if(['J','Q','K'].includes(r)) return [10]; return [parseInt(r,10)]; } function handValues(hand){ // returns best value <=21 or smallest if bust let totals = [0]; for(const c of hand){ const vals = cardValue(c); const newTotals = []; for(const t of totals){ for(const v of vals){ newTotals.push(t+v); } } totals = Array.from(new Set(newTotals)); } // separate <=21 and >21 const valid = totals.filter(t=>t<=21); if(valid.length) return Math.max(...valid); return Math.min(...totals); } function renderHand(el,hand,hideFirst=false){ el.innerHTML=''; hand.forEach((c,i)=>{ const div = document.createElement('div'); div.className='card'+(c.suit==='♥'||c.suit==='♦'?' red':''); if(hideFirst && i===0){ div.className='card back'; div.textContent='TERSEMBUNYI'; } else{ const top = document.createElement('div'); top.textContent = c.rank + ' ' + c.suit; // top-left const bot = document.createElement('div'); bot.style.alignSelf='flex-end'; bot.textContent = c.rank + ' ' + c.suit; // bottom-right div.appendChild(top); div.appendChild(bot); } el.appendChild(div); }); } function updateUI(){ renderHand(dealerHandEl,dealer,dealerHidden); renderHand(playerHandEl,player,false); dealerValueEl.textContent = dealerHidden ? '??' : 'Nilai: '+handValues(dealer); playerValueEl.textContent = 'Nilai: '+handValues(player); balanceEl.textContent = balance; currentBetEl.textContent = currentBet; } function startRound(){ if(inRound) return; const bet = Number(betInput.value) || 0; if(bet <=0 || bet > balance){ alert(' BANK TIDAK CUKUP! '); return; } currentBet = bet; balance -= bet; inRound=true; dealerHidden=true; messageEl.textContent=''; makeDeck(); shuffle(); dealer = [deck.pop(), deck.pop()]; player = [deck.pop(), deck.pop()]; // Check for natural blackjack updateUI(); if(handValues(player)===21){ dealerHidden=false; updateUI(); const dealerVal = handValues(dealer); if(dealerVal===21){ // push balance += currentBet; messageEl.textContent = 'Tie (seri). Taruhan dikembalikan.'; } else { // player blackjack 3:2 const payout = Math.floor(currentBet * 2.5); balance += payout; messageEl.textContent = 'Blackjack! You Win.'; } inRound=false; currentBet=0; updateUI(); } else { updateUI(); } } function playerHit(){ if(!inRound) return; player.push(deck.pop()); updateUI(); const val = handValues(player); if(val>21){ // bust dealerHidden=false; messageEl.textContent='Bust! Dealer Win!'; inRound=false; currentBet=0; updateUI(); } } function playerStand(){ if(!inRound) return; dealerHidden=false; // reveal dealer // dealer plays while(handValues(dealer)<17){ dealer.push(deck.pop()); } const pv = handValues(player); const dv = handValues(dealer); if(dv>21 || pv>dv){ // player wins const payout = currentBet*2; balance += payout; messageEl.textContent='You Win!'; } else if(pv===dv){ // push balance += currentBet; messageEl.textContent='Tie (seri).'; } else { messageEl.textContent='Dealer Win!'; } inRound=false; currentBet=0; updateUI(); } function playerDouble(){ if(!inRound) return; if(balance < currentBet){ alert('Bank tidak cukup untuk double.'); return; } // double: take exactly one card then stand balance -= currentBet; currentBet = currentBet*2; player.push(deck.pop()); updateUI(); const val = handValues(player); if(val>21){ dealerHidden=false; messageEl.textContent='Bust setelah double. Dealer Win!'; inRound=false; currentBet=0; updateUI(); return; } playerStand(); } // Events betBtn.addEventListener('click', startRound); hitBtn.addEventListener('click', playerHit); standBtn.addEventListener('click', playerStand); doubleBtn.addEventListener('click', playerDouble); newRoundBtn.addEventListener('click', ()=>{ // reset everything if(inRound){ if(!confirm('Masih dalam ronde. Ingin reset?')) return; } balance = 1000; currentBet=0; inRound=false; dealer=[]; player=[]; deck=[]; dealerHidden=true; messageEl.textContent='Bank di-reset.'; updateUI(); }); // keyboard shortcuts window.addEventListener('keydown', e=>{ if(e.key==='h') playerHit(); if(e.key==='s') playerStand(); if(e.key==='d') playerDouble(); if(e.key==='Enter') startRound(); }); // initial UI updateUI();